export const ensureArray = (thing: any) =>
  Array.isArray(thing) ? thing : [thing]

export const toObject = (thing: any) =>
  Array.isArray(thing)
    ? thing.reduce((previousValue, i) => ({ ...previousValue, [i]: true }), {})
    : thing || {}

export const map = (value: any, x1: any, y1: any, x2 = 0, y2 = 100) =>
  ((value - x1) * (y2 - x2)) / (y1 - x1) + x2

/**
 * 一维数组转二维数组
 * @param array  [key1, value1, key2, value2, ...]
 * @param size  2
 * @return returnArray [ [key1, XX], [key2, value2], ...]
 */
export const chunk = (array: any, size: any) =>
  Array.from({ length: Math.ceil(array.length / size) }, (v, i) =>
    array.slice(i * size, i * size + size)
  )

export const zip = (array: any, ...arrays: any) =>
  array.map((v: any, i: any) =>
    arrays.reduce(
      (previousValue: any, array_: any) => [...previousValue, array_[i]],
      [v]
    )
  )

/**
 * 组队
 * @param stop [key, value] / [value]
 * @return pairArray [key, value] / [null, value]
 */
export const toPair = (stop: any) =>
  stop.length === 2 ? stop : [null, ...stop]

export const toBins = (stops: any) => {
  const other = stops.find(([input]: any) => input === null)
  return stops.reduce((previousValue: any, [low, out]: any, i: number) => {
    if (i === stops.length - 1) {
      previousValue.push([low, out])
    } else if (out !== other[1]) {
      previousValue.push([[low, stops[i + 1][0]], out])
    }
    return previousValue
  }, [])
}

export const createElement = (tag: any, options = {}) => {
  const { classes, styles, attributes, content, appendTo }: any = options
  const element = document.createElement(tag)
  if (classes) {
    ensureArray(classes).forEach((c) => element.classList.add(c))
  }
  if (styles) {
    Object.entries(styles).forEach((property) =>
      element.style.setProperty(...property)
    )
  }
  if (attributes) {
    Object.entries(attributes).forEach(([attribute, value]) => {
      element[attribute] = value
    })
  }
  element.append(
    ...ensureArray(content).filter(
      (child) => child !== null && child !== undefined
    )
  )
  if (appendTo) {
    // appendTo.appendChild(element)
    appendTo.append(element)
  }
  return element
}

export const serializeLabel = (value: any, metadata: any) => {
  const { labels = {}, unit = '' } = metadata || {}
  return Array.isArray(value)
    ? value[1]
      ? value.map((v) => labels[v] || `${v}${unit}`).join(' - ')
      : `+${labels[value[0]] || `${value[0]}${unit}`}`
    : value !== null
    ? labels[value] || `${value}${unit}`
    : labels.other || 'other'
}
